#include "node.h"
#include <fstream>
#include <iostream>
#include <assert.h>
#include <string>

using std::string;
void load(std::fstream& file);
void buildNode(string input, Node* parent);
float distance(Node* current, Node* goal);
float square2(float number);

using namespace std;
using std::string;
using namespace::std;

Node::Node(Vertex* state, Node* parent, int boardCost){
	Node::parent = parent;
	Node::state = state;

	numberOfChildren = 0;
	hasChild = false;

	if(parent != 0){
		pathCost = parent->getPathCost() + boardCost;//distance(this, parent);
		parent->addChild(this);
		isRoot = false;
	}else{
		pathCost = 0;
	}
	
	next = 0;
}

/** Node created with the default constructor is considered a root */
Node::Node(){
	parent = NULL;
	isRoot = true;
	hasChild = false;
	pathCost = 0;
	next = 0;
}

/** Returns parent node */
Node* Node::getParent(){
	return parent;
}
/** Sets parent node */
void Node::setParent(Node* newParent){
	parent = newParent;
}

/** Sets isRoot variable */
void Node::setHasParent(bool var){
	isRoot = var;
}
/** Prints all values of node */
void Node::printState(){
	cout << "(" << state->x << "," << state->y << ")";

}
/** Returns hasChild */
bool Node::hasChildren(){
	return hasChild;
}
/** Returns hasParent */
bool Node::hasParent(){
	if(isRoot){
		return false;
	}
	return true;
}
/** Copies state into node's state array */
void Node::setState(Vertex* state){
	Node::state = state;
}

/** Sets hasChild value */
void Node::setHasChild(bool value){
	hasChild = value;
}
/** Returns pointer to node's state */
Vertex* Node::getState(){
	return Node::state;
}
/** Returns string name of node (not used) */
string Node::getData(){
	return Node::name;
}


/** Gets fvalue */
float Node::getfValue(){
	return fValue;
}
/** Sets fvalue */
void Node::setfValue(float newfValue){
	fValue = newfValue;
}

/** Used to add child to a node which allows multiple children */
void Node::addChild(Node* newChild){
	children.push_back(newChild);
	numberOfChildren = numberOfChildren + 1;

	hasChild = true;
}


/** Deallocates all memory for Node's nodes */
void Node::destroyNode(Node* root){
	if(root->hasChildren() == true){
		//destroyNode(root->getChild());
	}
	delete root;
}


/** Reutrns the path cost to get to current node */
int Node::getPathCost(){
	return pathCost;
}

/* Returns the straight line distance from current state to goal state. */
float distance(Node* current, Node* goal){
	float distance = sqrt(square2(goal->state->x - current->state->x) + square2(goal->state->y - current->state->y));
	return distance;
}

float square2(float number){
	return number * number;
}
